/*
 * $Id: Object.m,v 1.12 2005-11-24 10:04:22 bacon Exp $
 */

#include <xpo/bas/Object.h>
#include <xp/bas/memory.h>

/* TODO: remove the 2 files below */
#include <xp/bas/stdio.h>
#include <xp/bas/stdlib.h>

static inline struct objc_object* __alloc (struct objc_class* class)
{
	xp_size_t size;
	struct objc_object* obj;

	size = xp_sizeof(struct objc_object) + class->instance_size;
	obj = (struct objc_object*)xp_calloc(1, size);
	if (obj == XP_NULL) return nil;

#if defined(__APPLE__) || defined(__MACOSX__)
	obj->isa = class;
#else
	obj->class_pointer = class;
#endif
	return obj;
}

@implementation XpObject

+ (id) alloc
{
	return __alloc (self);
}

+ (id) new
{
	id obj = [self alloc];
	if (obj == nil) return nil;
	return [obj init];
}

- (id) init
{
	return self;
}

- (void) dealloc
{
	if (self != nil) xp_free (self);
}

- (Class) class
{
	return object_get_class (self);
}

- (Class) superclass
{
	return object_get_super_class (self);
}

- (const char*) className
{
	/*if (object_is_class(self))*/ return object_get_class_name(self);
	/*return object_get_class_name(object_get_class(self));*/
}

- (xp_bool_t) conformsToProtocol: (Protocol*)protocol
{
	struct objc_protocol_list* p;
	xp_size_t i;

	p = ((struct objc_class*)self)->class_pointer->protocols;
	while (p != XP_NULL) {
		for (i = 0; i < p->count; i++) {
			if ([p->list[i] conformsTo: protocol]) return xp_true;
		}	
		p = p->next;
	}

	if ([self superclass] != nil) 
		return [[self superclass] conformsToProtocol: protocol];

	return xp_false;
}

#if defined(__APPLE__) || defined(__MACOSX__)
- (id) forward: (SEL)sel: (marg_list)args
{
	return self;
}
#endif

- (void) subclassResponsibility
{
	xp_printf (XP_TEXT("subclass responsibility"));
	xp_exit (1);	
}

@end
